//============================================================================
// Name        : ROMS_main.cpp
// Author      : Muhammad Ghufron Mahfudhi, David Andrew Verona, Eric Marshall Garfinkle
// Version     : Step A, Step B, Step C, Step D
// Copyright   : Your copyright notice
// Description : C++ project Part II for your class (121, or 112) 
//============================================================================
//
#include "Simple_window.h"
#include "Graph.h"
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Text_Display.H>

#include "ROMS_Menu.h"

using namespace std;
using namespace ROMS;
using namespace Graph_lib;

//types we need for a ROMS GUI interface-- a memu_bar and a place to display text and a means of attaching them to a Window.

namespace Graph_lib {
//------------------------------------------------------------------------------
	struct Window_text_display : Widget {
		Window_text_display(Point XY, int W, int H, string L, Callback cb): Widget(XY, W, H, L, cb)
		{}
		void set_buffer(string s);
		void attach(Window&);
	private:
		Fl_Text_Buffer data;
		Fl_Text_Display *ptd;

	};
	void Window_text_display::attach(Window& win)
	{
		ptd = new Fl_Text_Display(loc.x, loc.y, width, height, label.c_str());
		ptd->buffer(&data);
		/* MGM B2: Start (to change the font into courier) */
		ptd->textfont(FL_COURIER);
		/* MGM B2: End */
		pw  = (Fl_Widget*) ptd;
		pw->callback(reinterpret_cast<Fl_Callback*>(do_it), &win); // pass the window
		own = &win;
	}
	void Window_text_display::set_buffer(string s) 
	{
		data.text(s.c_str());
	}

//------------------------------------------------------------------------------
	struct Menu_bar : Widget {
		Menu_bar(Point XY, int W, int H, Callback cb): Widget(XY, W, H, "", cb)
		{}
		void menu(Fl_Menu_Item *ma);
		void attach(Window&);
	private:
		Fl_Menu_Bar *pmb;
		Fl_Menu_Item *ma;

	};
	void Menu_bar::attach(Window& win)
	{
		pmb = new Fl_Menu_Bar(loc.x, loc.y, width, height);
		pmb->menu(ma);
		pw  = (Fl_Widget*) pmb;
		pw->callback(reinterpret_cast<Fl_Callback*>(do_it), &win); // pass the window
		own = &win;
	}
	void Menu_bar::menu(Fl_Menu_Item *m) 
	{
		ma = m;
	}
}

//header declarations
void do_about_box(Window&);
void do_help_box(Window&);
void do_read(Window&, ROMS_Menu&, string, string, Msg_type);
//EMG C
void do_find_menu_item_sales_box(Window& w);
void do_add_cat(Window& w);
//void do_graph_sales_month(Window& w);

void Main_Window_CB(Fl_Widget*, void*);
void Menu_Bar_CB (Fl_Widget*, void*);
/* MGM C: Start */
void do_server_sales_box(Window&); 
void do_category_sales_box(Window& w); 
void do_add_order_item(Window& w); 
void do_add_order(Window& w); 
/* MGM C: End */
//DAV
void do_table_sales_box(Window& w);
void do_add_menu_item(Window& w);

/* MGM D: Start */
void do_graph_order_sales_box(Window& w);
void do_graph_table_sales_box(Window& w);
void do_graph_category_sales_box(Window& w);
/* MGM D: End */

//global data
bool main_window_click = false;
bool menu_bar_click = false;
bool main_click_enabled = true;//used to force serialization on clicks
bool button_click_enable = false;	//MGM C
int window_userdata;
int menu_userdata;	//MGM C
ROMS_Menu m;

//main window menu bar
//Note: for expediancy sake, to define the menu bar below we used an FLTK type Fl_Menu_Item. 
//This makes our program  directly tied to FLTK instead of Dr. Stroustrup's interface Graph_lib.
//We don't like this, but we did it to save time, which often happens in the real world.
//A better solution is to write code to hide this in the implementation of the Graph_lib::Menu_bar, but that means adding
//changes to it and getting general agreement with Dr. Stroustrup. Subsequent testing and distribution would take time we don't have.
//An extra credit exercise is to see if you can eliminate direct references in your code to FLTK types like we have here
Fl_Menu_Item menu_bar[] = {
 {"Read", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Recipes", 0,  (Fl_Callback*)Main_Window_CB, Address (Read_recipes_ingredients), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Orders", 0,  (Fl_Callback*)Main_Window_CB, Address (Read_orders), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Menu Items", 0,  (Fl_Callback*)Main_Window_CB, Address (Read_category_menu_items), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 {"Show", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Orders", 0,  (Fl_Callback*)Main_Window_CB, Address (Show_order), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Recipes", 0,  (Fl_Callback*)Main_Window_CB, Address (Show_recipe), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Menu Items", 0,  (Fl_Callback*)Main_Window_CB, Address (Show_menu), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Categories", 0,  (Fl_Callback*)Main_Window_CB, Address (Show_categories), 0, FL_NORMAL_LABEL, 0, 14, 0},//added EMG B.3
 {"Order Items", 0,  (Fl_Callback*)Main_Window_CB, Address (Show_orderitems), 0, FL_NORMAL_LABEL, 0, 14, 0},//same as above
 {0,0,0,0,0,0,0,0,0},
 {"Find", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Category Sales", 0,  (Fl_Callback*)Main_Window_CB, Address (Find_category_sales), 0, FL_NORMAL_LABEL, 0, 14, 0},//modded EMG
 {"Table Sales", 0,  (Fl_Callback*)Main_Window_CB, Address (Find_table_sales), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Menu Item Sales", 0,  (Fl_Callback*)Main_Window_CB, Address (Find_menu_item_sales), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Server Sales", 0,  (Fl_Callback*)Main_Window_CB, Address (Find_server_sales), 0, FL_NORMAL_LABEL, 0, 14, 0}, //added by MGM C
 {0,0,0,0,0,0,0,0,0},
 {"Update", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Add Order Item", 0,  (Fl_Callback*)Main_Window_CB, Address (Update_add_order_item), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Add Menu Item", 0,  (Fl_Callback*)Main_Window_CB, Address (Update_add_menu_item), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Add Category", 0,  (Fl_Callback*)Main_Window_CB, Address (Update_add_category), 0, FL_NORMAL_LABEL, 0, 14, 0},//modded EMG
 {0,0,0,0,0,0,0,0,0},
 {"Graph", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},//added by MGM EMG D
 {"Monthly Order Sales", 0,  (Fl_Callback*)Main_Window_CB, Address (Graph_order_sales), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Table Sales", 0,  (Fl_Callback*)Main_Window_CB, Address (Graph_table_sales), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Monthly Category Sales", 0,  (Fl_Callback*)Main_Window_CB, Address (Graph_category_sales), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 {"About", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Info", 0,  (Fl_Callback*)Main_Window_CB, Address (About_info), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Help", 0,  (Fl_Callback*)Main_Window_CB, Address (About_help), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 {"Exit", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Save and exit", 0,  (Fl_Callback*)Main_Window_CB, Address (Exit_program), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 {0,0,0,0,0,0,0,0,0}
};


//call back functions
//Changed by MGM, because oi_cb (order item) and recps_cb (recipe) were swapped before
void recps_cb(Address addr, Address) // callback for recipes button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Recipes_button));
}
void order_cb(Address addr, Address) // callback for orders button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Orders_button));
}
void cat_cb(Address addr, Address) // callback for category button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Categories_button));
}
void mi_cb(Address addr, Address) // callback for menu item button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Menu_items_button));
}
void oi_cb(Address addr, Address) // callback for order item button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Tables_button));
}
/* MGM C: Start */
void ss_cb(Address addr, Address) //callback for calculate server sales button
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Calculate_server_sales));
}
void cs_cb(Address addr, Address) //callback for calculate category sales button
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Calculate_category_sales));
}
void addOrderItem_cb(Address addr, Address) //callback for add order item button
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Add_order_item));
}
void addOrder_cb(Address addr, Address) //callback for add order button
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Add_order));
}
void addOrderCurrentTime_cb(Address addr, Address) //callback for add order button
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Add_order_current_time));
}
void deleteOrderItem_cb(Address addr, Address) //callback for add order button
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Delete_order_item));
}
/* MGM C: End */

//DAV C
void ts_cb(Address addr, Address) //callback for calculate table sales button
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Calculate_table_sales));
}
void addMenuItem_cb(Address addr, Address) //callback for add menu item button
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Add_menu_item));
}

 void display_cb(Address addr, Address) // callback for display window
{
	Main_Window_CB((Fl_Widget*) addr, Address (Display_window));
}
void menu_bar_cb(Address addr, Address)//callback for menu bar
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Menu_bar_cb));
}
//EMG C
void find_menu_item_sales_cb(Address addr, Address)//callback for menu bar
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Calculate_menu_item_sales));
}
void add_cat_cb(Address addr, Address)//callback for menu bar
{
	Menu_Bar_CB((Fl_Widget*) addr, Address (Update_add_category));
}
 //add callback for button to call findMenuItemSales

void Menu_Bar_CB (Fl_Widget*, void* ud) {
	cout << "Menu Bar Callback" << " Userdata=" << (int) ud << "\n";
	menu_bar_click = true;
	menu_userdata = (int) ud;	//MGM C
}
void Main_Window_CB(Fl_Widget*, void* ud) {
	if(main_click_enabled)//don't signal the window click if main loop is active
	{
		cout << "Main Window Callback" << " Userdata=" << (int) ud << "\n";
		window_userdata = (int) ud;
		main_window_click = true;
		main_click_enabled = false; //main loop active on current click
	}
}
//wait functions for callbacks to be executed
void wait_for_main_window_click() {
	while (!main_window_click) 
		Fl::wait();
	main_window_click = false;
	Fl::redraw();
}
void wait_for_menu_bar_click() {
	while (!menu_bar_click)
		Fl::wait();
	menu_bar_click = false;
	Fl::redraw();
}
int main()
{
	//create the main window and display it
	//ROMS_Menu m;
    Window sw(600, 500, "Restaurant Order Management System");
    Button recps(Point(40, 50), 100, 30, "Recipes", recps_cb);
	sw.attach(recps);
	Button order(Point(40, 100), 100, 30, "Orders", order_cb);
	sw.attach(order);
	Button cat(Point(40, 150), 100, 30, "Categories", cat_cb);
	sw.attach(cat);
	Button mi(Point(40, 200), 100, 30, "Menu Items", mi_cb);
	sw.attach(mi);
	Button ci(Point(40, 250), 100, 30, "Order Items", oi_cb);
	sw.attach(ci);
    sw.callback((Fl_Callback*)Main_Window_CB, Address (Exit_program));
	Menu_bar mb(Point(0, 0), 600, 30, menu_bar_cb);
    mb.menu(menu_bar);
	sw.attach(mb);

	Window_text_display t(Point(150,50),400, 400, "Data Display", display_cb );
	t.set_buffer("No Data Loaded\n");
	sw.attach(t);
 	sw.resizable(&sw);
	

	//main loop to execute user clicks on the main window
	//do you understand how this loop works compared to the way the main loop worked in Part I of the project?
	try {
		
		while(true) {
			main_click_enabled = true;
			wait_for_main_window_click();
			cout << "Act on userdata = " << window_userdata << endl;
			switch(window_userdata) 
			{
				//need to complete all the menu cases
				case Read_recipes_ingredients:
					do_read(sw, m, "recipes.dat", "Open Recipes/Ingredients File", Read_recipes_ingredients);
					break;
				case Read_orders:
					do_read(sw, m, "orders.dat", "Open Order/Order Items File", Read_orders);
					break;
				case Read_category_menu_items:
					do_read(sw, m, "catmenu.dat", "Open Category/Menu Item File", Read_category_menu_items);
					break;
				case About_info:
					do_about_box(sw);
					break;
				case About_help://EMG B.3
					do_help_box(sw);
					break;
				case Find_menu_item_sales://EMG C
					do_find_menu_item_sales_box(sw);
					break;
				case Update_add_category:
					do_add_cat(sw);
					break;
				/*case Graph_sales_month:
					do_graph_sales_month(sw);
					break;*/
				//Modified by MGM B2
				case Tables_button: case Orders_button: case Categories_button: case Recipes_button: 
				case Menu_items_button: case Show_order: case Show_menu: case Show_recipe:
				//modified further EMG B.3
				case Show_categories: case Show_orderitems:
					t.set_buffer(m.show_button((Msg_type) window_userdata).c_str());
					break;
				case Exit_program:
					cout << "save files and exit\n";
					m.SaveExit();
					exit(0); //exit program
					break;
				/* MGM C : Start */
				case Find_server_sales:
					do_server_sales_box(sw);
					break;
				case Find_category_sales:
					do_category_sales_box(sw);
					break;
				case Update_add_order_item:
					do_add_order_item(sw);
					break;
				/* MGM C : End */
				case Find_table_sales: //DAV C
					do_table_sales_box(sw);
					break;
				case Update_add_menu_item: //DAV C
					do_add_menu_item(sw);
					break;

				/* MGM D: Start */
				case Graph_order_sales:
					do_graph_order_sales_box(sw);
					break;
				case Graph_table_sales:
					do_graph_table_sales_box(sw);
					break;
				case Graph_category_sales:
					do_graph_category_sales_box(sw);
					break;
				/* MGM D: End */

				default:
					cout << "case not implemented\n";
			}
		}
		return 0;
	}
	catch(exception& e) {
		cerr << "exception: " << e.what() << '\n';
		return 1;
	}
	catch (...) {
		cerr << "Some exception\n";
		return 2;
	}
}
//show about box info window
void do_about_box(Window& w) 
{
	Window ab(Point(w.x()+100, w.y()+100), 640, 480, "About Box");
	//ab.color(Color::white);
	ab.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_about_box));
	/*Text msg(Point(15,50), "Ward Project Part II: Restaurant Order Management System");
	msg.set_color(Color::black);
	ab.attach(msg);
	wait_for_menu_bar_click();
	ab.detach(msg);//clean up window*/
	Image about(Point(0,0), "CSCE _About.jpg");
	ab.attach(about);
	wait_for_menu_bar_click();
	ab.detach(about);   //clean up window
	
	return;
}
void do_help_box(Window& w) //EMG B.3
{
	Window ab(Point(w.x()+100, w.y()+100), 500, 300, "Help");
	ab.color(Color::white);
	ab.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_help_box));
	Text msg(Point(15,50), "This is Group 9's Restuarant Order Management System");
	Text msg1(Point(15,75), "To start, first input data, by reading the .dat files");
	Text msg2(Point(15,100), "with the input data. Then click the buttons to view");
	Text msg3(Point(15,125), "the relivant data, or click on the menu options to get");
	Text msg4(Point(15,150), "specific functions.");
	msg.set_color(Color::black);
	msg1.set_color(Color::black);
	msg2.set_color(Color::black);
	msg3.set_color(Color::black);
	msg4.set_color(Color::black);
	ab.attach(msg);
	ab.attach(msg1);
	ab.attach(msg2);
	ab.attach(msg3);
	ab.attach(msg4);
	wait_for_menu_bar_click();
	ab.detach(msg);
	ab.detach(msg1);
	ab.detach(msg2);
	ab.detach(msg3);
	ab.detach(msg4);
	return;
}
//EMG C start
void do_find_menu_item_sales_box(Window& w) 
{
	string s;
	Window ab(Point(w.x()+100, w.y()+100), 600, 300, "Find :: Menu Item Sales");
	ab.color(Color::white);
	ab.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_fmi_box));
	
	Text msg(Point(15,50), "Which Menu Item do you want to see sales for?");
		msg.set_color(Color::black);
	In_box menuIDBox(Point(15,65), 100, 20, s);
	Text text(Point(15,120), " ");
		text.set_color(Color::black);
	Button findItem(Point(120, 65), 100, 20, "Find", find_menu_item_sales_cb);
	ab.attach(text);
	ab.attach(msg);
	ab.attach(menuIDBox);
	ab.attach(findItem);
	wait_for_menu_bar_click();
	button_click_enable = true;
	
	while(menu_userdata != Close_fmi_box) {
		cout << "Act on userdata = " << menu_userdata <<' '<< Calculate_menu_item_sales<<endl;
		if(menu_userdata == Calculate_menu_item_sales)
		{
			if(menuIDBox.get_int() != -999999)
			{
				cout << menuIDBox.get_int() << endl;
				text.set_label(m.findMenuItemSales(menuIDBox.get_int() , "Menu and Order Items"));
				
			}
			else
			{
				text.set_label("Menu ID Box is empty. Please input a menu ID.");
				
			}
		}
		wait_for_menu_bar_click();
		button_click_enable = true;
	}
	//detachstuff here
	ab.detach(msg);
	return;
}
void do_add_cat(Window& w)
{
	string s;
	Window ab(Point(w.x()+100, w.y()+100), 600, 300, "Find :: Menu Item Sales");
	ab.color(Color::white);
	ab.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_add_cat_box));
	
	Text msg(Point(15,50), "Enter the name of the category you would like to add...");
		msg.set_color(Color::black);
	In_box catNameBox(Point(15,65), 100, 20, s);
	Text text(Point(15,120), " ");
		text.set_color(Color::black);
	Button addItem(Point(120, 65), 100, 20, "Add", add_cat_cb);
	ab.attach(text);
	ab.attach(msg);
	ab.attach(catNameBox);
	ab.attach(addItem);
	wait_for_menu_bar_click();
	button_click_enable = true;
	
	while(menu_userdata != Close_add_cat_box) {
		cout << "Act on userdata = " << menu_userdata <<' '<< Update_add_category<<endl;
		if(menu_userdata == Update_add_category)
		{
			if(!catNameBox.get_string().empty())
			{
				cout << catNameBox.get_string() << endl;
				text.set_label(m.addCategory(catNameBox.get_string() , "Menu and Order Items"));
				
			}
			else
			{
				text.set_label("Category Box is empty. Please input a category name.");
				
			}
		}
		wait_for_menu_bar_click();
		button_click_enable = true;
	}
	//detachstuff here
	ab.detach(msg);
	return;
}
//EMG C end
void do_read(Window& w, ROMS_Menu& m, string dfn, string msg, Msg_type type)
{
	//Here again we linked our code directly to the FLTK library instead of creating an interface in our Graph_lib interface to FLTK
	//We did it for lack of time, which reflects the real word. Unfortunately if we wanted to move our code to a different graphics
	//library, we have to change our code and not just our Graphic_lib implementation. we are using the FLTK file chooser directly.
	Fl_File_Chooser fc(dfn.c_str(), "*.dat", Fl_File_Chooser::CREATE, msg.c_str());
	fc.show();
	while (fc.shown())
		Fl::wait();	//wait for OK or Cancel button
	if(0!=fc.value())//make sure there is a string to use as a filename
	{
		string fname = fc.value();
		switch(type) {
			case Read_recipes_ingredients:
				m.read_recipes_ingredients(fname);
				break;
			case Read_orders:
				m.Read_orders(fname);
				break;
			case Read_category_menu_items:
				m.read_catprds(fname);
				break;
			default:
				throw InvalidType();
		}
	}
	return;
}
/*
void do_graph_sales_month(Window& w)
{
	vector<double> total;
	string s="test";
	string output=m.findOrderSalesByMonth(total,s);
	cout<<output;
}
*/

//DAV C
void do_table_sales_box(Window& w)
{
	Window se(Point(w.x()+100, w.y()+100), 600, 300, "Find Table Sales");
	//se.color(Color::white);
	se.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_table_sales_box));
	In_box tableIDBox(Point(125, 20), 50, 20, "Input Table ID: ");
	Button genTable(Point(300, 20), 100, 20, "Calculate", ts_cb);
	Text info(Point(20, 80), "Info: ");
	Text text(Point(20, 100), "Please input table ID.");
	se.attach(tableIDBox);
	se.attach(genTable);
	se.attach(info);
	se.attach(text);

	wait_for_menu_bar_click();
	button_click_enable = true;

	while(menu_userdata != Close_table_sales_box) {
		cout << "Act on userdata = " << menu_userdata << endl;
		if(menu_userdata == Calculate_table_sales)
		{
			if(tableIDBox.get_int() != -999999)
			{
				cout << tableIDBox.get_int() << endl;
				text.set_label(m.tableSales(tableIDBox.get_int() , "Orders, Menu Items, and Order Items"));
				
			}
			else
			{
				text.set_label("Table ID Box is empty. Please input a table ID.");
				
			}
		}
		wait_for_menu_bar_click();
		button_click_enable = true;
	}

	se.detach(tableIDBox);   //clean up window
	se.detach(genTable);   //clean up window
	se.detach(info);
	se.detach(text);   //clean up window
	return;
}
void do_add_menu_item(Window& w)
{
	Window se(Point(w.x()+100, w.y()+100), 800, 400, "Update Order Item");
	//se.color(Color::white);
	se.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_add_menu_item));
	Text inputCat(Point(20, 30), "Input Category: ");
	Text inputRec(Point(20, 60), "Input Recipe ID: ");
	Text inputName(Point(20, 90), "Input Menu Name: ");
	Text inputPrice(Point(20, 120), "Input Menu Price: ");
	Text inputDesc(Point(20, 140), "Input Description: ");
	In_box catBox(Point(170, 15), 120, 20, "");
	In_box recBox(Point(170, 45), 120, 20, "");
	In_box nameBox(Point(170, 75), 120, 20, "");
	In_box priceBox(Point(170, 105), 120, 20, "");
	In_box descBox(Point(170, 135), 120, 100, "");
	Button addMenuItem(Point(170, 265), 120, 20, "Add Menu Item", addMenuItem_cb);
	//Button addOrder(Point(320, 45), 120, 20, "Add Order", addOrder_cb );
	//Button deleteOrderItem(Point(320, 135), 120, 20, "Delete Order Item", deleteOrderItem_cb);
	Text info(Point(20, 300), "Info: ");
	Text text(Point(20, 320), "Please input category, recipe ID, menu name, menu price, and description.");
	se.attach(inputCat);
	se.attach(inputRec);
	se.attach(inputName);
	se.attach(inputPrice);
	se.attach(inputDesc);
	se.attach(catBox);
	se.attach(recBox);
	se.attach(nameBox);
	se.attach(priceBox);
	se.attach(descBox);
	se.attach(addMenuItem);
	//se.attach(addOrder);
	//se.attach(deleteOrderItem);
	se.attach(info);
	se.attach(text);
	
	wait_for_menu_bar_click();
	button_click_enable = true;

	while(menu_userdata != Close_add_menu_item) {
		cout << "Act on userdata = " << menu_userdata << endl;
		if(menu_userdata == Add_menu_item)
		{
			if(!catBox.get_string().empty() && recBox.get_int() != -999999 && !nameBox.get_string().empty() && !priceBox.get_string().empty() && !descBox.get_string().empty())
			{
				text.set_label(m.addMenuItem(catBox.get_string(), recBox.get_int(), nameBox.get_string(), priceBox.get_string(), descBox.get_string() , "Order Items, Orders, and Menu Items"));	
			}
			else
			{
				text.set_label("Category/Recipe ID/Menu Name/Menu Price/Description Box(es) is(are) empty. Please input all of them.");	
			}
		}
		
		wait_for_menu_bar_click();
		button_click_enable = true;
	}

	se.detach(inputCat);			//clean up window
	se.detach(inputRec);			//clean up window
	se.detach(inputName);			//clean up window
	se.detach(inputPrice);			//clean up window
	se.detach(inputDesc);			//clean up window
	se.detach(catBox);				//clean up window
	se.detach(recBox);				//clean up window
	se.detach(nameBox);				//clean up window
	se.detach(priceBox);			//clean up window
	se.detach(descBox);				//clean up window
	se.detach(addMenuItem);			//clean up window
	//se.attach(addOrder);			//clean up window
	//se.attach(deleteOrderItem);
	se.detach(info);				//clean up window
	se.detach(text);				//clean up window

	return;
}

/* MGM C: Start */
void do_server_sales_box(Window& w)
{
	Window se(Point(w.x()+100, w.y()+100), 600, 300, "Find Server Sales");
	//se.color(Color::white);
	se.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_server_sales_box));
	In_box serverIDBox(Point(125, 20), 50, 20, "Input Server ID: ");
	Button genServer(Point(300, 20), 100, 20, "Calculate", ss_cb);
	Text info(Point(20, 80), "Info: ");
	Text text(Point(20, 100), "Please input server ID.");
	se.attach(serverIDBox);
	se.attach(genServer);
	se.attach(info);
	se.attach(text);

	wait_for_menu_bar_click();
	button_click_enable = true;

	while(menu_userdata != Close_server_sales_box) {
		cout << "Act on userdata = " << menu_userdata << endl;
		if(menu_userdata == Calculate_server_sales)
		{
			if(serverIDBox.get_int() != -999999)
			{
				cout << serverIDBox.get_int() << endl;
				text.set_label(m.serverSales(serverIDBox.get_int() , "Orders, Menu Items, and Order Items"));
				
			}
			else
			{
				text.set_label("Server ID Box is empty. Please input a server ID.");
				
			}
		}
		wait_for_menu_bar_click();
		button_click_enable = true;
	}

	se.detach(serverIDBox);   //clean up window
	se.detach(genServer);   //clean up window
	se.detach(info);
	se.detach(text);   //clean up window
	return;
}
void do_category_sales_box(Window& w)
{
	Window se(Point(w.x()+100, w.y()+100), 600, 300, "Find Category Sales");
	//se.color(Color::white);
	se.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_category_sales_box));
	In_box categoryBox(Point(125, 20), 100, 20, "Input Category: ");
	Button genCategory(Point(300, 20), 100, 20, "Calculate", cs_cb);
	Text info(Point(20, 80), "Info: ");
	Text text(Point(20, 100), "Please input Category.");
	se.attach(categoryBox);
	se.attach(genCategory);
	se.attach(info);
	se.attach(text);
	
	wait_for_menu_bar_click();
	button_click_enable = true;

	while(menu_userdata != Close_category_sales_box) {
		cout << "Act on userdata = " << menu_userdata << endl;
		if(menu_userdata == Calculate_category_sales)
		{
			if(!categoryBox.get_string().empty())
			{
				text.set_label(m.categorySales(categoryBox.get_string() , "Orders, Menu Items, and Order Items"));
				
			}
			else
			{
				text.set_label("Category Box is empty. Please input a Category.");
				
			}
		}
		wait_for_menu_bar_click();
		button_click_enable = true;
	}

	se.detach(categoryBox);   //clean up window
	se.detach(genCategory);   //clean up window
	se.detach(info);
	se.detach(text);   //clean up window
	return;
}
void do_add_order_item(Window& w)
{
	Window se(Point(w.x()+100, w.y()+100), 800, 400, "Update Order Item");
	//se.color(Color::white);
	se.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_add_order_item));
	Text inputSeat(Point(20, 30), "Input Seat: ");
	Text inputOrder(Point(20, 60), "Input Order ID: ");
	Text inputMenu(Point(20, 90), "Input Menu Item: ");
	Text inputQty(Point(20, 120), "Input Quantity: ");
	In_box seatBox(Point(170, 15), 120, 20, "");
	In_box orderBox(Point(170, 45), 120, 20, "");
	In_box menuBox(Point(170, 75), 120, 20, "");
	In_box qtyBox(Point(170, 105), 120, 20, "");
	Button addOrderItem(Point(170, 135), 120, 20, "Add Order Item", addOrderItem_cb);
	Button addOrder(Point(320, 45), 120, 20, "Add Order", addOrder_cb );
	Button deleteOrderItem(Point(320, 135), 120, 20, "Delete Order Item", deleteOrderItem_cb);
	Text info(Point(20, 200), "Info: ");
	Text text(Point(20, 220), "Please seat ID, order ID, menu item, and quantity.");
	se.attach(inputSeat);
	se.attach(inputOrder);
	se.attach(inputMenu);
	se.attach(inputQty);
	se.attach(seatBox);
	se.attach(orderBox);
	se.attach(menuBox);
	se.attach(qtyBox);
	se.attach(addOrderItem);
	se.attach(addOrder);
	se.attach(deleteOrderItem);
	se.attach(info);
	se.attach(text);
	
	wait_for_menu_bar_click();
	button_click_enable = true;

	while(menu_userdata != Close_add_order_item) {
		cout << "Act on userdata = " << menu_userdata << endl;
		if(menu_userdata == Add_order_item)
		{
			if(!seatBox.get_string().empty() && orderBox.get_int() != -999999 && !menuBox.get_string().empty() && qtyBox.get_int() != -999999)
			{
				text.set_label(m.addOrderItem(seatBox.get_string(), orderBox.get_int(), menuBox.get_string(), qtyBox.get_int() , "Order Items, Orders, and Menu Items"));	
			}
			else
			{
				text.set_label("Seat ID/Order ID/Menu Item/Quantity Box(es) is(are) empty. Please input all of them.");	
			}
		}
		else if(menu_userdata == Add_order)
		{
			do_add_order(se);
		}
		else if(menu_userdata == Delete_order_item)
		{
			if(!seatBox.get_string().empty() && orderBox.get_int() != -999999 && !menuBox.get_string().empty() && qtyBox.get_int() != -999999)
			{
				text.set_label(m.delOrderItem(seatBox.get_string(), orderBox.get_int(), menuBox.get_string(), qtyBox.get_int() , "Order Items, Orders, and Menu Items"));	
			}
			else
			{
				text.set_label("Seat ID/Order ID/Menu Item/Quantity Box(es) is(are) empty. Please input all of them.");	
			}
		}
		wait_for_menu_bar_click();
		button_click_enable = true;
	}

	se.detach(inputSeat);		//clean up window
	se.detach(inputOrder);		//clean up window
	se.detach(inputMenu);		//clean up window
	se.detach(inputQty);		//clean up window
	se.detach(seatBox);			//clean up window
	se.detach(orderBox);		//clean up window
	se.detach(menuBox);			//clean up window
	se.detach(qtyBox);			//clean up window
	se.detach(addOrderItem);	//clean up window
	se.detach(addOrder);		//clean up window
	se.detach(deleteOrderItem);	//clean up window
	se.detach(info);			//clean up window
	se.detach(text);			//clean up window
	return;
}
void do_add_order(Window& w)
{
	Window se(Point(w.x()+100, w.y()+100), 800, 400, "Add Order");
	//se.color(Color::white);
	se.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_add_order));
	Text inputServer(Point(20, 30), "Input Server ID: ");
	Text inputTable(Point(20, 60), "Input Table ID: ");
	Text inputDate(Point(20, 90), "Input Date: ");
	Text formatDate(Point(300, 90), "(yyyy/m/d)");
	Text inputTime(Point(20, 120), "Input Time: ");
	Text FormatTime(Point(300, 120), "(h:m)");
	In_box serverBox(Point(170, 15), 120, 20, "");
	In_box tableBox(Point(170, 45), 120, 20, "");
	In_box dateBox(Point(170, 75), 120, 20, "");
	In_box timeBox(Point(170, 105), 120, 20, "");
	Button addOrder(Point(170, 155), 120, 40, "Add Order", addOrder_cb);
	Button addOrderCurrentTime(Point(320, 155), 300, 40, "Add Order Using Current Date and Time", addOrderCurrentTime_cb);
	Text info(Point(20, 300), "Info: ");
	Text text(Point(20, 320), "Please server ID and table ID (date and time too if you do not want to use current date and time).");
	se.attach(inputServer);
	se.attach(inputTable);
	se.attach(inputDate);
	se.attach(formatDate);
	se.attach(inputTime);
	se.attach(serverBox);
	se.attach(tableBox);
	se.attach(dateBox);
	se.attach(timeBox);
	se.attach(FormatTime);
	se.attach(addOrder);
	se.attach(addOrderCurrentTime);
	se.attach(info);
	se.attach(text);
	
	wait_for_menu_bar_click();
	button_click_enable = true;

	while(menu_userdata != Close_add_order) {
		cout << "Act on userdata = " << menu_userdata << endl;
		if(menu_userdata == Add_order)
		{
			if(serverBox.get_int() != 999999 && tableBox.get_int() != -999999 && !dateBox.get_string().empty() && !timeBox.get_string().empty())
			{
				text.set_label(m.addOrder(serverBox.get_int(), tableBox.get_int(), dateBox.get_string(), timeBox.get_string(), 1, "Orders"));
			}
			else
			{
				text.set_label("Server ID/Table ID/Date/Time Box(es) is(are) empty. Please input all of them.");	
			}
		}
		else if(menu_userdata == Add_order_current_time)
		{
			if(serverBox.get_int() != 999999 && tableBox.get_int() != -999999)
			{
				text.set_label(m.addOrder(serverBox.get_int(), tableBox.get_int(), "", "", 2, "Orders"));
			}
			else
			{
				text.set_label("Server ID/Table ID Box(es) is(are) empty. Please input all of them.");	
			}
		}
		wait_for_menu_bar_click();
		button_click_enable = true;
	}

	se.detach(inputServer);			//clean up window
	se.detach(inputTable);			//clean up window
	se.detach(inputDate);			//clean up window
	se.detach(formatDate);			//clean up window
	se.detach(inputTime);			//clean up window
	se.detach(serverBox);			//clean up window
	se.detach(tableBox);			//clean up window
	se.detach(dateBox);				//clean up window
	se.detach(timeBox);				//clean up window
	se.detach(FormatTime);			//clean up window
	se.detach(addOrder);			//clean up window
	se.detach(addOrderCurrentTime);	//clean up window
	se.detach(info);				//clean up window
	se.detach(text);				//clean up window
	return;
}
/* MGM C: End */

/* MGM D: Start */
void do_graph_order_sales_box(Window& w)
{
	Window se(Point(w.x()+100, w.y()+100), 600, 550, "Graph of Total Order Sales by Month");
	se.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_graph_order));

	//call function
	vector<double> total;
	string s = "Order, Order Items, and Menu items";
	m.findOrderSalesByMonth(total, s);
	
	//set
	Axis xa(Axis::x, Point(80,400), 450, 12, ""); // make an Axis
	Text jan(Point(80+37-10, 420), "Jan");
	Text feb(Point(80+(37*2)-10, 420), "Feb");
	Text mar(Point(80+(37*3)-10, 420), "Mar");
	Text apr(Point(80+(37*4)-10, 420), "Apr");
	Text may(Point(80+(37*5)-10, 420), "May");
	Text jun(Point(80+(37*6)-10, 420), "Jun");
	Text jul(Point(80+(37*7)-10, 420), "Jul");
	Text aug(Point(80+(37*8)-10, 420), "Aug");
	Text sep(Point(80+(37*9)-10, 420), "Sep");
	Text oct(Point(80+(37*10)-10, 420), "Oct");
	Text nov(Point(80+(37*11)-10, 420), "Nov");
	Text des(Point(80+(37*12)-10, 420), "Des");
	Text month(Point(80+(450/2)-20,450), "Month");
	Text info(Point(20, 500), "Info:");
	Text info2(Point(20, 520), s);
	Axis ya(Axis::y, Point(80, 400), 360, 20, "Sales ($)"); // make an Ordinat
	Text s100(Point(50, 400-(5*18)+5), "100");
	Text s200(Point(50, 400-(10*18)+5), "200");
	Text s300(Point(50, 400-(15*18)+5), "300");
	Text s400(Point(50, 400-(20*18)+5), "400");
	Open_polyline poly;
	if(total.size() != 0)
	{
		cout << "Total monthly sales:\n";
		for(int i = 0; i < total.size();i++)
		{
			cout << total[i] << endl;
			poly.add(Point(80+(37*(i+1)), (double)400-((double)total[i]*(double)360/(double)400)));
		}
	}
	poly.set_color(Color::red);	
	
	//attach
	se.attach(xa);
	se.attach(jan);
	se.attach(feb);
	se.attach(mar);
	se.attach(apr);
	se.attach(may);
	se.attach(jun);
	se.attach(jul);
	se.attach(aug);
	se.attach(sep);
	se.attach(oct);
	se.attach(nov);
	se.attach(des);
	se.attach(month);
	se.attach(info);
	se.attach(info2);
	se.attach(ya);
	se.attach(s100);
	se.attach(s200);
	se.attach(s300);
	se.attach(s400);
	se.attach(poly);

	//wait and detach
	wait_for_menu_bar_click();
	se.detach(xa);
	se.detach(jan);
	se.detach(feb);
	se.detach(mar);
	se.detach(apr);
	se.detach(may);
	se.detach(jun);
	se.detach(jul);
	se.detach(aug);
	se.detach(sep);
	se.detach(oct);
	se.detach(nov);
	se.detach(des);
	se.detach(month);
	se.detach(info);
	se.detach(info2);
	se.detach(ya);
	se.detach(s100);
	se.detach(s200);
	se.detach(s300);
	se.detach(s400);
	se.detach(poly);

	return;
}

void do_graph_table_sales_box(Window& w)
{
	Window se(Point(w.x()+100, w.y()+100), 600, 550, "Graph of Total Sales by Table");
	se.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_graph_table));

	//call function
	vector<double> total;
	string s = "Order Items and Menu items";
	m.findSalesByTable(total, s);

	//set
	Axis xa(Axis::x, Point(80,400), 450, 8, ""); // make an Axis
	Text a(Point(80+56-5, 420), "A");
	Text b(Point(80+(56*2)-5, 420), "B");
	Text c(Point(80+(56*3)-5, 420), "C");
	Text d(Point(80+(56*4)-5, 420), "D");
	Text e(Point(80+(56*5)-5, 420), "E");
	Text f(Point(80+(56*6)-5, 420), "F");
	Text g(Point(80+(56*7)-5, 420), "G");
	Text h(Point(80+(56*8)-5, 420), "H");
	Text labelx(Point(80+(450/2)-50,450), "Seat Table");
	Text info(Point(20, 500), "Info:");
	Text info2(Point(20, 520), s);
	Axis ya(Axis::y, Point(80, 400), 360, 20, "Sales ($)"); // make an Ordinat
	Text s100(Point(50, 400-(5*18)+5), "100");
	Text s200(Point(50, 400-(10*18)+5), "200");
	Text s300(Point(50, 400-(15*18)+5), "300");
	Text s400(Point(50, 400-(20*18)+5), "400");
	Closed_polyline poly[8];
	if(total.size() != 0)
	{
		cout << "Total table sales:\n";
		
		for(int i = 0; i < 8; i++)
		{
			cout << total[i] << endl;
			poly[i].add(Point(80+(56*(i+1))-15, 400));
			poly[i].add(Point(80+(56*(i+1))+15, 400));
			poly[i].add(Point(80+(56*(i+1))+15, (double)400-((double)total[i]*(double)360/(double)400)));
			poly[i].add(Point(80+(56*(i+1))-15, (double)400-((double)total[i]*(double)360/(double)400)));
			poly[i].set_fill_color(Color::red);
		}
	}
	
	//attach
	se.attach(xa);
	se.attach(a);
	se.attach(b);
	se.attach(c);
	se.attach(d);
	se.attach(e);
	se.attach(f);
	se.attach(g);
	se.attach(h);
	se.attach(labelx);
	se.attach(info);
	se.attach(info2);
	se.attach(ya);
	se.attach(s100);
	se.attach(s200);
	se.attach(s300);
	se.attach(s400);
	if(total.size() != 0)
	{
		for(int i = 0; i < 8; i++)
		{
			se.attach(poly[i]);
		}
	}
	

	//wait and detach
	wait_for_menu_bar_click();
	se.detach(xa);
	se.detach(a);
	se.detach(b);
	se.detach(c);
	se.detach(d);
	se.detach(e);
	se.detach(f);
	se.detach(g);
	se.detach(h);
	se.detach(labelx);
	se.detach(info);
	se.detach(info2);
	se.detach(ya);
	se.detach(s100);
	se.detach(s200);
	se.detach(s300);
	se.detach(s400);
	if(total.size() != 0)
	{
		for(int i = 0; i < 8; i++)
		{
			se.detach(poly[i]);
		}
	}

	return;
}

void do_graph_category_sales_box(Window& w)
{
	Window se(Point(w.x()+100, w.y()+100), 700, 550, "Graph of Total Category Sales by Month");
	se.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_graph_category));

	//call function
	vector<double> totalMonth;
	vector< vector<double> > totalCat;
	vector<string> catName;
	string s = "Categories, Order Items, and Menu items";
	m.findCategorySalesByMonth(totalMonth, totalCat, catName, s);

	//set
	Axis xa(Axis::x, Point(80,400), 450, 12, ""); // make an Axis
	Text jan(Point(80+37-10, 420), "Jan");
	Text feb(Point(80+(37*2)-10, 420), "Feb");
	Text mar(Point(80+(37*3)-10, 420), "Mar");
	Text apr(Point(80+(37*4)-10, 420), "Apr");
	Text may(Point(80+(37*5)-10, 420), "May");
	Text jun(Point(80+(37*6)-10, 420), "Jun");
	Text jul(Point(80+(37*7)-10, 420), "Jul");
	Text aug(Point(80+(37*8)-10, 420), "Aug");
	Text sep(Point(80+(37*9)-10, 420), "Sep");
	Text oct(Point(80+(37*10)-10, 420), "Oct");
	Text nov(Point(80+(37*11)-10, 420), "Nov");
	Text des(Point(80+(37*12)-10, 420), "Des");
	Text labelx(Point(80+(450/2)-20,450), "Month");
	Text info(Point(20, 500), "Info:");
	Text info2(Point(20, 520), s);
	Axis ya(Axis::y, Point(80, 400), 370, 20, "Sales (%)"); // make an Ordinat
	Text s100(Point(50, 400-(5*18)+5), "25");
	Text s200(Point(50, 400-(10*18)+5), "50");
	Text s300(Point(50, 400-(15*18)+5), "75");
	Text s400(Point(50, 400-(20*18)+5), "100");
	Text legend(Point(570,45), "Legend:");
	vector<Closed_polyline*> polyMonth;
	vector<Text*> textLegend;
	vector<Rectangle*> colorLegend;
	if(totalMonth.size() != 0)
	{
		cout << "Total category sales:\n";
		
		for(int i = 0; i < 12; i++)
		{
			cout << "Month " << i+1 << ": " << totalMonth[i] << endl;
			double hi = 400;
			if(totalMonth[i] == 0)
			{
				//If no sale in a month, make empty bar (white)
				Closed_polyline* poly = new Closed_polyline();
				(*poly).set_fill_color(Color::white);
				(*poly).add(Point(80+(37*(i+1))-12, hi));
				(*poly).add(Point(80+(37*(i+1))+12, hi));
				(*poly).add(Point(80+(37*(i+1))+12, hi-(double)360));
				(*poly).add(Point(80+(37*(i+1))-12, hi-(double)360));
				polyMonth.push_back(poly);
			}
			else
			{
				for(int j = 0; j < totalCat[i].size(); j++)
				{
					//If there is sales in a month, make colorful bar
					cout << totalCat[i][j] << endl;
					Closed_polyline* poly = new Closed_polyline();
					(*poly).set_fill_color((60+(j*50))%255);
					(*poly).add(Point(80+(37*(i+1))-12, hi));
					(*poly).add(Point(80+(37*(i+1))+12, hi));
					(*poly).add(Point(80+(37*(i+1))+12, hi-(totalCat[i][j]*(double)360/totalMonth[i])));
					(*poly).add(Point(80+(37*(i+1))-12, hi-(totalCat[i][j]*(double)360/totalMonth[i])));
					polyMonth.push_back(poly);
					hi -= ((double)totalCat[i][j]*(double)360/totalMonth[i]);
				}
			}
		}

		//Legend for empty bar
		Rectangle* rec0 = new Rectangle(Point(570,55),30, 20);
		(*rec0).set_fill_color(Color::white);
		colorLegend.push_back(rec0);
		Text* t0 = new Text(Point(610, 70), "Empty");
		textLegend.push_back(t0);
		//Legend for colorful bar
		for(int i = 0; i < catName.size(); i++)
		{
			Rectangle* rec = new Rectangle(Point(570, 85 + (30 * i)), 30, 20);
			(*rec).set_fill_color((60+(i*50))%255);
			colorLegend.push_back(rec);
			Text* t = new Text(Point(610, 100 + (30 * i)), catName[i]);
			textLegend.push_back(t);
		}
	}
	
	//attach
	se.attach(xa);
	se.attach(jan);
	se.attach(feb);
	se.attach(mar);
	se.attach(apr);
	se.attach(may);
	se.attach(jun);
	se.attach(jul);
	se.attach(aug);
	se.attach(sep);
	se.attach(oct);
	se.attach(nov);
	se.attach(des);
	se.attach(labelx);
	se.attach(info);
	se.attach(info2);
	se.attach(ya);
	se.attach(s100);
	se.attach(s200);
	se.attach(s300);
	se.attach(s400);
	se.attach(legend);
	if(totalMonth.size() != 0)
	{
		for(int i = 0; i < polyMonth.size(); i++)
		{
			se.attach(*polyMonth[i]);
		}
		for(int i = 0; i < colorLegend.size(); i++)
		{
			se.attach(*colorLegend[i]);
		}
		for(int i = 0; i < textLegend.size(); i++)
		{
			se.attach(*textLegend[i]);
		}
	}

	//wait and detach
	wait_for_menu_bar_click();
	se.detach(xa);
	se.detach(jan);
	se.detach(feb);
	se.detach(mar);
	se.detach(apr);
	se.detach(may);
	se.detach(jun);
	se.detach(jul);
	se.detach(aug);
	se.detach(sep);
	se.detach(oct);
	se.detach(nov);
	se.detach(des);
	se.detach(labelx);
	se.detach(info);
	se.detach(info2);
	se.detach(ya);
	se.detach(s100);
	se.detach(s200);
	se.detach(s300);
	se.detach(s400);
	se.detach(legend);
	if(totalMonth.size() != 0)
	{
		for(int i = 0; i < polyMonth.size(); i++)
		{
			se.detach(*polyMonth[i]);
		}
		for(int i = 0; i < colorLegend.size(); i++)
		{
			se.detach(*colorLegend[i]);
		}
		for(int i = 0; i < textLegend.size(); i++)
		{
			se.detach(*textLegend[i]);
		}
	}

	return;
}
/* MGM D: End */